import { Request, Response } from 'express';
import { Req, Body, Post, UseBefore, Res, Get, Controller } from 'routing-controllers';
import { Container } from 'typedi';
import { LoginUserDto } from '@/dtos';
import { RequestWithUser } from '@/interfaces';
import { ValidationMiddleware } from '@middlewares/validation.middleware';
import { AuthService } from '@services/auth.service';
import { ApiResponseBuilder } from '@utils/api-response-builder';
import { Log, LogBizId, LogOperation } from '@decorators/logs.decorators';
import { OpenAPI } from 'routing-controllers-openapi';

@Controller('/auth')
export class AuthController {
  public auth = Container.get(AuthService);

  @Post('/login')
  @Log({ bizType: 'auth', operation: LogOperation.LOGIN, bizId: LogBizId.LOGIN })
  @UseBefore(ValidationMiddleware(LoginUserDto, true))
  @OpenAPI({ summary: '用户登录' })
  async logIn(@Req() req: Request, @Res() res: Response, @Body() userData: LoginUserDto) {
    const { normalized, accessToken, refreshToken, isDoubleToken } = await this.auth.login(req, userData);
    return new ApiResponseBuilder(req, res).success({
      user: normalized,
      token: { accessToken, refreshToken },
      isDoubleToken,
    });
  }

  @Get('/logout')
  @Log({ bizType: 'auth', operation: LogOperation.LOGOUT, bizId: LogBizId.LOGOUT })
  @OpenAPI({ summary: '用户登出' })
  async logOut(@Req() req: RequestWithUser, @Res() res: Response) {
    await this.auth.logout(req.user);
    return new ApiResponseBuilder(req, res).success();
  }

  @Get('/refresh')
  @OpenAPI({ summary: '用户刷新登录状态' })
  async refresh(@Req() req: RequestWithUser, @Res() res: Response) {
    const { accessToken, refreshToken, isDoubleToken } = await this.auth.refresh(req.user);
    return new ApiResponseBuilder(req, res).success({ token: { accessToken, refreshToken }, isDoubleToken });
  }

  @Get('/heartbeat')
  @OpenAPI({ summary: '心跳检测' })
  async heartbeat(@Req() req: RequestWithUser, @Res() res: Response) {
    await this.auth.heartbeat(req.user);
    return new ApiResponseBuilder(req, res).success(req.user);
  }
}
